﻿using System;
using System.Web;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using System.IO;
using System.Web.Security;

namespace Wedn.Core.Utility
{

    /// <summary>
    /// 字符串处理工具类
    /// </summary>
    public class StringHelper
    {
        #region 字符串转换和操作

        /// <summary>
        /// 将指定普通文本转换成HTML文本, 返回转换后HTML文本
        /// </summary>
        /// <param name="content">要转换的普通文本</param>
        /// <returns>HTML文本</returns>
        public static string TextToHtml(string content)
        {
            StringBuilder sb = new StringBuilder(content);
            sb.Replace("&", "&amp;");
            sb.Replace("<", "&lt;");
            sb.Replace(">", "&gt;");
            sb.Replace("\"", "&quot;");
            //     sb.Replace("\'", "&#39;");
            sb.Replace(" ", "&nbsp;");
            sb.Replace("\t", "&nbsp;&nbsp;");
            sb.Replace("\r", "");
            sb.Replace("\n", "<br />");
            return sb.ToString();
            //  return ShitEncode(sb.ToString());
            //return content.Replace(" ", "&nbsp;").Replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;").
            //    Replace("<", "&lt;").Replace(">", "&gt;").Replace("\r", "").Replace("\n", "<br />");
        }

        /// <summary>
        /// 将指定HTML文本转换成普通文本, 返回转换后普通文本
        /// </summary>
        /// <param name="content">要转换的HTML文本</param>
        /// <returns>普通文本</returns>
        public static string HtmlToText(string content)
        {
            StringBuilder sb = new StringBuilder(content);
            sb.Replace("<br />", "\n");
            sb.Replace("<br/>", "\n");
            //  sb.Replace("\r", "");
            sb.Replace("&nbsp;&nbsp;", "\t");
            sb.Replace("&nbsp;", " ");
            sb.Replace("&#39;", "\'");
            sb.Replace("&quot;", "\"");
            sb.Replace("&gt;", ">");
            sb.Replace("&lt;", "<");
            sb.Replace("&amp;", "&");
            return sb.ToString();
        }

        /// <summary>
        /// 对字符串进行 HTML 编码并返回已编码的字符串
        /// </summary>
        /// <param name="content">要编码的文本字符串</param>
        /// <returns>HTML 已编码的文本</returns>
        public static string HtmlEncode(string content)
        {
            return HttpContext.Current.Server.HtmlEncode(content);
        }

        /// <summary>
        ///  对 HTML 编码的字符串进行解码，并返回已解码的字符串
        /// </summary>
        /// <param name="content">要解码的文本字符串</param>
        /// <returns>已解码的字符串</returns>
        public static string HtmlDecode(string content)
        {
            return HttpContext.Current.Server.HtmlDecode(content);
        }

        /// <summary>
        /// 对 URL 字符串进行编码, 返回 URL 字符串的编码结果
        /// </summary>
        /// <param name="str">要编码的文本</param>
        /// <returns>一个已编码的字符串</returns>
        public static string UrlEncode(string str)
        {
            return HttpUtility.UrlEncode(str);
        }

        /// <summary>
        /// 对 URL 字符串进行解码, 返回 URL 字符串的解码结果
        /// </summary>
        /// <param name="str">要解码的文本</param>
        /// <returns>解码结果</returns>
        public static string UrlDecode(string str)
        {
            return HttpUtility.UrlDecode(str);
        }

        /// <summary>
        /// 移除Html标记
        /// </summary>
        /// <param name="Htmlstring">包括HTML的源码</param>   
        ///<returns>已经去除后的文字</returns>   
        public static string RemoveHtml(string Htmlstring)
        {
            //删除脚本和嵌入式CSS   
            Htmlstring = Regex.Replace(Htmlstring, @"<script[^>]*?>.*?</script>", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"<style[^>]*?>.*?</style>", "", RegexOptions.IgnoreCase);

            //删除HTML   
            Regex regex = new Regex("<.+?>", RegexOptions.IgnoreCase);
            Htmlstring = regex.Replace(Htmlstring, "");
            Htmlstring = Regex.Replace(Htmlstring, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"([\r\n])[\s]+", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"-->", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"<!--.*", "", RegexOptions.IgnoreCase);

            Htmlstring = Regex.Replace(Htmlstring, @"&(quot|#34);", "\"", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(amp|#38);", "&", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(lt|#60);", "<", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(gt|#62);", ">", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(nbsp|#160);", "   ", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(iexcl|#161);", "\xa1", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(cent|#162);", "\xa2", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(pound|#163);", "\xa3", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(copy|#169);", "\xa9", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&#(\d+);", "", RegexOptions.IgnoreCase);

            Htmlstring.Replace("<", "");
            Htmlstring.Replace(">", "");
            Htmlstring.Replace("\r\n", "");

            return Htmlstring;
        }

        /// <summary>
        /// 编码成 sql 文本可以接受的格式
        /// </summary>
        public static string SqlEncode(string s)
        {
            if (null == s || 0 == s.Length)
            {
                return string.Empty;
            }
            return s.Trim().Replace("'", "''");
        }

        /// <summary>
        /// string型转换为int型,转换失败返回缺省值
        /// </summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="def">缺省值</param>
        /// <returns>转换后的int类型结果</returns>
        public static int StrToInt(string str, int def)
        {
            if (IsInt(str))
                return int.Parse(str);
            else
                return def;
        }

        /// <summary>
        /// 返回URL中结尾的文件名
        /// </summary>		
        public static string GetFileName(string url)
        {
            if (url == null)
            {
                return "";
            }
            //是否有参数
            if (url.IndexOf("?") != -1)
            {
                //去掉参数
                string noquery = url.Substring(0, url.IndexOf("?"));

                //根据/分组
                string[] filenames = noquery.Split(new char[] { '/' });

                //文件名
                string filename = filenames[filenames.Length - 1];

                return filename;
            }
            else
            {
                return System.IO.Path.GetFileName(url);
            }
        }

        /// <summary>
        /// 返回字符串真实长度, 1个汉字长度为2
        /// </summary>
        /// <returns></returns>
        public static int GetLength(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return 0;
            }
            return Encoding.Default.GetBytes(str).Length;
        }

        /// <summary>
        /// 将DateTime时间换成中文
        /// </summary>
        /// <example>
        /// 2012-12-21 12:12:21.012 → 1月前
        /// 2011-12-21 12:12:21.012 → 1年前
        /// </example>
        /// <param name="datetime">时间</param>
        /// <returns></returns>
        public static string DateTimeToChsStr(DateTime datetime)
        {
            TimeSpan ts = DateTime.Now - datetime;
            if ((int)ts.TotalDays >= 365)
            {
                return (int)ts.TotalDays / 365 + "年前";
            }
            if ((int)ts.TotalDays >= 30 && ts.TotalDays <= 365)
            {
                return (int)ts.TotalDays / 30 + "月前";
            }
            if ((int)ts.TotalDays == 1)
            {
                return "昨天";
            }
            if ((int)ts.TotalDays == 2)
            {
                return "前天";
            }
            if ((int)ts.TotalDays >= 3 && ts.TotalDays <= 30)
            {
                return (int)ts.TotalDays + "天前";
            }
            if ((int)ts.TotalDays == 0)
            {
                if ((int)ts.TotalHours != 0)
                {
                    return (int)ts.TotalHours + "小时前";
                }
                else
                {
                    if ((int)ts.TotalMinutes == 0)
                    {
                        return "刚刚";
                    }
                    else
                    {
                        return (int)ts.TotalMinutes + "分钟前";
                    }
                }
            }
            return datetime.ToString("yyyy年MM月dd日");
        }

        /// <summary>
        /// 从字符串的指定位置截取指定长度的子字符串(过时)
        /// </summary>
        /// <param name="str">原字符串</param>
        /// <param name="startIndex">子字符串的起始位置</param>
        /// <param name="length">子字符串的长度</param>
        /// <returns>子字符串</returns>
        public static string CutString(string str, int startIndex, int length)
        {
            return CutString(str, startIndex, length, string.Empty);
        }

        /// <summary>
        /// 从字符串的指定位置开始截取到字符串结尾的了符串
        /// </summary>
        /// <param name="str">原字符串</param>
        /// <param name="startIndex">子字符串的起始位置</param>
        /// <returns>子字符串</returns>
        public static string CutString(string str, int length)
        {
            return CutString(str, 0, length, string.Empty);
        }

        /// <summary>
        /// 截取字符
        /// </summary>
        /// <param name="str"></param>
        /// <param name="length"></param>
        /// <param name="def"></param>
        /// <returns></returns>
        public static string CutString(string str, int length, string def)
        {
            return CutString(str, 0, length, def);
        }

        public static string CutString(string str, int startIndex, int length, string def)
        {
            if (startIndex >= 0)
            {
                if (length < 0)
                {
                    length = length * -1;
                    if (startIndex - length < 0)
                    {
                        length = startIndex;
                        startIndex = 0;
                    }
                    else
                    {
                        startIndex = startIndex - length;
                    }
                }
                if (startIndex > str.Length)
                {
                    return "";
                }
            }
            else
            {
                if (length < 0)
                {
                    return "";
                }
                else
                {
                    if (length + startIndex > 0)
                    {
                        length = length + startIndex;
                        startIndex = 0;
                    }
                    else
                    {
                        return "";
                    }
                }
            }
            if (str.Length - startIndex <= length)
            {
                length = str.Length - startIndex;
                def = string.Empty;
            }
            try
            {
                return str.Substring(startIndex, length) + def;
            }
            catch
            {
                return str + def;
            }
        }


        #endregion

        #region 字符串判断

        /// <summary>
        /// 检测指定字符串是否有SQL危险字符
        /// 没有返回true
        /// </summary>
        /// <param name="str">指定字符串</param>
        /// <returns>真或假</returns>
        public static bool IsSafeSqlString(string str)
        {
            return !Regex.IsMatch(str, @"[-|;|,|\/|\(|\)|\[|\]|\}|\{|%|@|\*|!|\']");
        }

        /// <summary>
        /// 判断指定字符串是否为合法IP地址
        /// </summary>
        /// <param name="str">指定字符串</param>
        /// <returns>真或假</returns>
        public static bool IsIP(string str)
        {
            return Regex.IsMatch(str, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
        }

        /// <summary>
        ///  判断指定字符串是否合法的日期格式
        /// </summary>
        /// <param name="str">指定字符串</param>
        /// <returns>真或假</returns>
        public static bool IsData(string str)
        {
            DateTime dt;
            return DateTime.TryParse(str, out dt);
            //try
            //{
            //    System.DateTime.Parse(value);
            //}
            //catch
            //{
            //    return false;
            //}
            //return true;
        }

        /// <summary>
        /// 判断指定的字符串是否为数字
        /// </summary>
        /// <param name="str">要确认的字符串</param>
        /// <returns>真或假</returns>
        public static bool IsInt(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return false;
            }
            return Regex.IsMatch(str, @"^(0|[1-9]\d*)$");
        }

        /// <summary>
        /// 判断指定的字符串是否为Url地址
        /// </summary>
        /// <param name="str">要确认的字符串</param>
        /// <returns>真或假</returns>
        public static bool IsHttpUrl(string str)
        {
            //return Regex.IsMatch(WebUrl, @"http://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?");
            //    return Regex.IsMatch(WebUrl, @"http://");
            return str.IndexOf("http://") != -1;
        }

        /// <summary>
        /// 判断指定的字符串是否为合法Email
        /// </summary>
        /// <param name="str">指定的字符串</param>
        /// <returns>真或假</returns>
        public static bool IsEmail(string str)
        {
            return Regex.IsMatch(str, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
        }

        #endregion

        #region 加密方法
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="str">要加密的字符串</param>
        /// <returns>加密后的字符串</returns>
        public static string Encrypt(string str)
        {
            string key = Config.EncryptKey;
            MD5 md5 = MD5.Create();
            byte[] bytes = md5.ComputeHash(Encoding.Default.GetBytes(key));
            StringBuilder eKey = new StringBuilder();
            foreach (var item in bytes)
            {
                eKey.Append(item.ToString("x"));
            }
            bytes = md5.ComputeHash(Encoding.Default.GetBytes(str + eKey.ToString()));
            StringBuilder pwd = new StringBuilder();
            foreach (var item in bytes)
            {
                pwd.Append(item.ToString("x"));
            }
            return pwd.ToString();
        }

        /// <summary>
        /// 将指定字符串以指定格式加密, 返回一个加密过后的字符串
        /// 不推荐使用!!
        /// </summary>
        /// <param name="str">指定字符串</param>
        /// <param name="format">指定格式("SHA1"|"MD5")</param>
        /// <returns></returns>
        public static string Encrypt(string str, string format)
        {
            return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, format);
        }

        /// <summary>
        /// 获取文件的MD5值
        /// </summary>
        /// <param name="stream">文件流</param>
        /// <returns>该文件的MD5值</returns>
        public static String GetStreamMD5(Stream stream)
        {
            string strResult = "";
            string strHashData = "";
            byte[] arrbytHashValue;
            System.Security.Cryptography.MD5CryptoServiceProvider oMD5Hasher =
                new System.Security.Cryptography.MD5CryptoServiceProvider();
            arrbytHashValue = oMD5Hasher.ComputeHash(stream); //计算指定Stream 对象的哈希值
            //由以连字符分隔的十六进制对构成的String，其中每一对表示value 中对应的元素；例如“F-2C-4A”
            strHashData = System.BitConverter.ToString(arrbytHashValue);
            //替换-
            strHashData = strHashData.Replace("-", "");
            strResult = strHashData;
            return strResult;
        }

        /// <summary>
        /// 加密一个Cookie值
        /// </summary>
        /// <param name="strCookie">要加密的Cookie值</param>
        /// <returns>加密后的Cookie值</returns>
        public static string EncryptCookie(string strCookie)
        {
            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(strCookie, true, 2);
            return FormsAuthentication.Encrypt(ticket);
        }

        /// <summary>
        /// 解密一个Cookie值
        /// </summary>
        /// <param name="strCookie">要解密的Cookie值</param>
        /// <returns>解密后的Cookie值</returns>
        public static string DecryptCookie(string strCookie)
        {
            return FormsAuthentication.Decrypt(strCookie).Name.ToString();
        }

        #endregion

        #region 常用操作
        /// <summary>
        /// 取客户端IP, 取不到则返回空字符串
        /// </summary>
        /// <returns>客户端IP</returns>
        public static string GetGuestIP()
        {
            string sIP = string.Empty;
            try
            {
                HttpRequest oHR = HttpContext.Current.Request;
                if (oHR.ServerVariables["HTTP_VIA"] != null) { sIP = oHR.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString().Split(',')[0].Trim(); }
                else { sIP = oHR.UserHostAddress; }
            }
            catch { }
            return sIP;
        }

        /// <summary>
        /// 取得Gravatar的MD5
        /// </summary>
        /// <param name="email">邮件地址</param>
        /// <returns>返回Gravatar用MD5值</returns>
        public string GravatarID(string email)
        {
            string result = string.Empty;
            if (!string.IsNullOrEmpty(email))
            {
                result = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(email, "MD5").ToLower();
            }
            return result;
        }
        #endregion

        static Random random = new Random(DateTime.Now.Millisecond);
        /// <summary>
        /// 获取随机数
        /// </summary>
        public static int GetRandom(int minNum, int maxNum)
        {
            return random.Next(minNum, maxNum);
        }

        #region 废弃
        ///// <summary>
        ///// 生成随机码
        ///// </summary>
        ///// <param name="length">长度</param>
        ///// <param name="isLower">是否转化成小写</param>
        ///// <returns></returns>
        //public static string RandCode(int length, bool isLower)
        //{
        //    char[] arrChar = new char[]{
        //   'a','b','d','c','e','f','g','h','i','j','k','l','m','n','p','r','q','s','t','u','v','w','z','y','x',
        //   '0','1','2','3','4','5','6','7','8','9',
        //   'A','B','C','D','E','F','G','H','I','J','K','L','M','N','Q','P','R','T','S','V','U','W','X','Y','Z'
        //  };

        //    StringBuilder num = new StringBuilder();

        //    Random rnd = new Random(DateTime.Now.Millisecond);
        //    for (int i = 0; i < length; i++)
        //    {
        //        num.Append(arrChar[rnd.Next(0, arrChar.Length)].ToString());

        //    }
        //    if (isLower)
        //    {
        //        return num.ToString().ToLower();
        //    }
        //    return num.ToString();
        //} 
        #endregion
    }
}
